﻿using System;
using System.Threading.Tasks;
using System.Collections.Generic;

using MyCtp;
using MyCtp.Model;

using WAF.EntityFramework;
using CtpTrader.Core.Common;


namespace CtpTrader.Core.Quote
{
    /// <summary>
    /// 行情数据接口操作类
    /// </summary>
    public class CtpQuote
    {
        /// <summary>
        /// 初始化并异步运行行情数据接口
        /// </summary>
        /// <param name="account">CTP账户</param>
        public CtpQuote(Account account)
        {
            this.ctpAccount = account;

            Init();
        }

        /// <summary>
        /// 释放行情接口对象
        /// </summary>
        public void Release()
        {
            ctpMdApi.Release();
        }


        /**************************** Private ****************************/

        /// <summary>
        /// 行情数据接口对象
        /// </summary>
        private MyCtp.CtpMdApi ctpMdApi;

        /// <summary>
        /// CTP账号
        /// </summary>
        private Account ctpAccount;

        /// <summary>
        /// 请求序号
        /// </summary>
        private int requestID = 0;


        /// <summary>
        /// 初始化并运行行情数据接口
        /// </summary>
        private void Init()
        {
            //初始化接口对象
            ctpMdApi = new CtpMdApi();

            //前置机地址
            ctpMdApi.RegisterFront(FrontManager.GetSimulationQuoteFront());

            //注册接口回调事件
            ctpMdApi.CtpMdEvents.OnFrontConnected       += this.OnFrontConnected;
            ctpMdApi.CtpMdEvents.OnRspUserLogin         += this.OnRspUserLogin;
            ctpMdApi.CtpMdEvents.OnRspSubMarketData     += this.OnRspSubMarketData;
            ctpMdApi.CtpMdEvents.OnRtnDepthMarketData   += this.OnRtnDepthMarketData;

            //初始化并运行
            ctpMdApi.Init();
            Task.Factory.StartNew(ctpMdApi.Join);
        }

        /// <summary>
        /// 连接前置机并登录
        /// </summary>
        private void OnFrontConnected()
        {
            CThostFtdcReqUserLoginField loginField = new CThostFtdcReqUserLoginField();

            loginField.BrokerID = this.ctpAccount.BrokerCode;
            loginField.UserID   = this.ctpAccount.Number;
            loginField.Password = this.ctpAccount.Password;

            ctpMdApi.ReqUserLogin(loginField, requestID++);
        }

        /// <summary>
        /// 用户登录应答
        /// </summary>
        private void OnRspUserLogin(CThostFtdcRspUserLoginField rspUserLoginfield, CThostFtdcRspInfoField rspInfoField, int nRequestID, bool bIsLast)
        {
            //登录成功则订阅行情
            if (rspInfoField.ErrorID == 0)
            {
                string[] subscribedInstruments = InstrumentManager.GetSubscribe();
                ctpMdApi.SubscribeMarketData(subscribedInstruments, subscribedInstruments.Length);
            }
        }

        /// <summary>
        /// 无用
        /// </summary>
        private void OnRspSubMarketData(CThostFtdcSpecificInstrumentField pSpecificInstrument, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {

        }

        /// <summary>
        /// 发布最新行情数据
        /// </summary>
        /// <param name="pDepthMarketData">深度行情数据结构</param>
        private void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField pDepthMarketData)
        {
            if (pDepthMarketData != null)
            {
                QuoteData quote = new QuoteData();

                quote.InstrumentID  = pDepthMarketData.InstrumentID;
                quote.Price         = pDepthMarketData.LastPrice;
                quote.UpdateTime    = DateTime.Parse(pDepthMarketData.UpdateTime);

                QuoteManager.GetInstance().EnqueueQuote(quote);
            }
        }
    }
}
